home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Copyright (C) 1992 WD Young, P.O. Box 632871, Nacogdoches TX 75963-2871
- **
- ** This file is distributed under the terms listed in the document
- ** "copying.wy", available from WD Young at the address above.
- ** A copy of "copying.wy" should accompany this file; if not, a copy
- ** should be available from where this file was obtained. This file
- ** may not be distributed without a verbatim copy of "copying.wy".
- **
- ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
- ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- /* This program decodes .IFS files into .KRD files */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <graphics.h>
- #include <math.h>
- #include <string.h>
- #define range domain
- #define max_scale 1.2
- int main(int argc, char **argv)
- {
- unsigned char domain [256][256][3];
- FILE *in, *krd, *out;
- char *inf, *krdf,level, test, dense = 64, sfactor = 1;
- unsigned char r, g, b;
- int xsize=256, ysize=256;
- int x, y, dx, dy, rx, ry, tsx, tsy, qx, qy;
- int ii[64][64], ddxx[64][64], ddyy[64][64];
- int transx[64][64], transy[64][64], yuv;
- float ss[64][64], oo[64][64], z;
- int level_table[64][64], patchsize[2] = {8, 4}, PS, PS1, number_ifses;
- int ix, iy, iddxx, iddyy, n, i, nflips=8, niterations, nummaps[3];
- float rms,s, o, yf, uf, vf, rf, gf, bf;
- int f11[] = {1, 0, -1, 0, 1, 0, -1, 0}, f12[] = {0, 1, 0, -1, 0, -1, 0, 1};
- int f21[] = {0, -1, 0, 1, 0, -1, 0, 1}, f22[] = {1, 0, -1, 0, -1, 0, 1, 0};
- char tgaheader[] = {0,0, 2,0, 0,0, 0,0, 0,0, 0,0, 0,1, 0,1, 24,32};
- struct trans_out {
- unsigned char dx;
- unsigned char dy;
- signed char scale : 7;
- short int offset : 7;
- unsigned short int flip : 3;
- unsigned short int size : 1;
- } transout[1];
-
- struct header_t { /* "should" be a 12 byte header... we'll see */
- long time; /* 4 bytes for compression time in seconds */
- short rms; /* 2 bytes for 100.*rms value */
- short add1; /* 2 bytes to be added later... room for growth */
- long add2; /* 4 bytes to be added later... room for growth */
- } header[1];
-
-
- if ((argc < 2)||(argc > 3)) {
- printf("\nusage: yuvunpak infile.ifs outfile.krd\n\n");
- printf("YUVUNPAK Version 2.0, Copyright (C) 1993, WD Young\n");
- printf("YUVUNPAK comes with ABSOLUTELY NO WARRANTY\n");
- printf("Please see files 'copying.wy' and 'copying' for details\n");
- printf("If these files are missing,\n");
- printf("write: WD Young, P.O. Box 632871, Nacogdoches TX 75963-2871\n");
- return 1;
- }
- niterations = 10;
- inf = argv[1]; krdf = argv[2];
-
- if ((in = fopen(inf, "rb")) == NULL) {
- fprintf(stderr, "Cannot open input file.\n");
- return 1;
- }
- if ((krd = fopen(krdf, "wb")) == NULL) {
- fprintf(stderr, "Cannot open output file.\n");
- return 1;
- }
-
- GrSetMode(GR_default_graphics);
- for (y = 0; y < 64; y++)
- GrSetColor(y,4*y,4*y,4*y);
- for (y = 64; y < 256; y++)
- GrSetColor(y,0,y/2,y);
-
- for (yuv = 0; yuv < 3; yuv++) {
- if (yuv >= 1) {
- dense = 16;
- patchsize[0] = 32;
- patchsize[1] = 16;
- sfactor = 4;
- }
- if (yuv == 2) fread(header, sizeof(struct header_t), 1, in);
- number_ifses = 0;
- for (ry = 0; ry < dense; ry+=2)
- for (rx = 0; rx < dense; rx+=2)
- {
- fread(transout, sizeof(struct trans_out), 1, in);
- level = transout[0].size;
- PS1 = patchsize[level] - 1;
- if (level == 0) number_ifses++;
- else number_ifses+=4;
- for (y = ry; y < ry+2; y++)
- for (x = rx; x < rx+2; x++) {
- level_table[y][x] = level;
- if (level == 1
- && (x != rx || y != ry)) fread(transout, sizeof(struct trans_out), 1, in);
- ddxx[y][x] = dx = sfactor*(int)transout[0].dx;
- ddyy[y][x] = dy = sfactor*(int)transout[0].dy;
- ii[y][x] = i = transout[0].flip;
- ss[y][x] = max_scale*(((float)transout[0].scale)/63.);
- oo[y][x] = transout[0].offset<<3;
- transx[y][x] = 2*patchsize[1]*x + PS1 - (f11[i]*(dx+PS1) + f12[i]*(dy+PS1));
- transy[y][x] = 2*patchsize[1]*y + PS1 - (f21[i]*(dx+PS1) + f22[i]*(dy+PS1));
- }
- }
- nummaps[yuv] = number_ifses;
- for (n = 0; n < niterations; n++)
- {
- /* Run through all non-overlapping NxN "R" blocks in the image */
- for (ry = 0; ry < dense; ry++)
- {
- for (rx = 0; rx < dense; rx++)
- {
- level = level_table[ry][rx];
- if (level == 0
- && (((rx % 2) !=0) || ((ry % 2) != 0))) continue; /* already covered in 8X8 */
- PS = patchsize[level];
- s = ss [ry] [rx];
- o = oo [ry] [rx];
- i = ii [ry] [rx];
- tsx = transx [ry] [rx];
- tsy = transy [ry] [rx];
- iddyy = ddyy [ry] [rx];
- iddxx = ddxx [ry] [rx];
- /*************************************************************************/
- /* Average & Transform the 256 2x2 "pixels" */
- /*************************************************************************/
- for (y = 0; y < 2*PS; y+=2)
- for (x = 0; x < 2*PS; x+=2)
- {
- dy = iddyy + y;
- dx = iddxx + x;
- z = (float)((domain[dy ][dx ][yuv]
- + domain[dy ][dx+1][yuv]
- + domain[dy+1][dx ][yuv]
- + domain[dy+1][dx+1][yuv]) >> 2);
-
- ix = (f11[i]*dx + f12[i]*dy + tsx) >> 1;
- iy = (f21[i]*dx + f22[i]*dy + tsy) >> 1;
- z = s*z + o;
- if (z > 255.) z = 255.; else if (z < 0.) z = 0.;
- range[iy][ix][yuv] = (unsigned char)z;
- GrPlot(ix,iy,((int)z)>>2);
- }
- }
- }
- }
-
- }
- for (y = 0; y < 18; y++)
- fputc(tgaheader[y],krd);
- for (y = 0; y < 256; y++)
- for (x = 0; x < 256; x++) {
- yf = (float)range[y][x][0];
- uf = (float)range[y][x][1];
- vf = (float)range[y][x][2];
- uf = 316.*uf/255. - 158.;
- vf = 224.*vf/255. - 112.;
- rf = (yf + 1.131*uf + 0.00698215*vf);
- if (rf < 0.) r = 0;
- else
- if (rf > 255.) r = 255;
- else r = (unsigned char)rf;
- gf = (yf - 0.576*uf - 0.3809*vf);
- if (gf < 0.) g = 0;
- else
- if (gf > 255.) g = 255;
- else g = (unsigned char)gf;
- bf = (yf + 0.005818*uf + 2.024*vf);
- if (bf < 0.) b = 0;
- else
- if (bf > 255.) b = 255;
- else b = (unsigned char)bf;
- fputc(b,krd);
- fputc(g,krd);
- fputc(r,krd);
- }
- fclose(in);
- fclose(krd);
- GrSetMode(GR_default_text);
- printf("ymap: %4i umap: %4i vmap: %4i\n",nummaps[0],nummaps[1],nummaps[2]);
- printf("compression ratio: %4.2f\n",192.*1024./((float)(nummaps[0]+nummaps[1]+nummaps[2])*4.25));
- printf("compression time: %5i\n",header[0].time);
- printf("pack rms: %4.1f\n",(((float)header[0].rms)/100.));
-
- /* All done. Whew... */
- return 0;
- }
-